Skip to content

Refactor ModuleFast to C# binary module — full cmdlet conversion with Artifacts Output Layout and Central Package Management#114

Draft
Copilot wants to merge 9 commits intomainfrom
copilot/refactor-project-to-csharp-modules
Draft

Refactor ModuleFast to C# binary module — full cmdlet conversion with Artifacts Output Layout and Central Package Management#114
Copilot wants to merge 9 commits intomainfrom
copilot/refactor-project-to-csharp-modules

Conversation

Copy link

Copilot AI commented Mar 20, 2026

Completes the migration of ModuleFast from a monolithic PowerShell script to a fully C# binary module. All public and private PowerShell functions are converted to C# cmdlets and helper classes. ModuleFast.psm1 is reduced to DLL loading and type accelerator registration only.

C# project structure

  • ModuleFast.slnx — SLNX solution file
  • src/ModuleFast/ModuleFast.csproj — targets net8.0; PackageReference entries carry no versions (governed by Directory.Packages.props)
  • Directory.Build.props — enables the .NET SDK Artifacts Output Layout (UseArtifactsOutput=true)
  • Directory.Packages.props — Central Package Management; declares Microsoft.PowerShell.SDK 7.4.6 and NuGet.Versioning 6.8.0

C# types (replacing PowerShell classes)

  • ModuleFastSpec — full port of the PS class; parses >=, <=, =, :, >, <, ! shorthand into NuGet.Versioning.VersionRange; implements IComparable/IEquatable<ModuleFastSpec> and implicit conversion to ModuleSpecification
  • ModuleFastInfo — port of the PS result type; IComparable, implicit ModuleSpecification conversion; ModuleVersion, Location, Guid are mutable (required by the installer)
  • ModuleFastClientHttpClient factory with PSCredential support, HTTP/3 opt-in, explicit decompression methods

New C# helper classes

  • NuGetModelsSystem.Text.Json models for the NuGet v3 Registration API
  • ModuleFastCache — singleton ConcurrentDictionary-based HTTP request cache (replaces $SCRIPT:RequestCache)
  • ModuleManifestReader — imports .psd1 manifests including dynamic-expression manifests via ScriptBlock.CheckRestrictedLanguage; fast version line scan
  • LocalModuleFinder — searches PSModulePath for installed modules matching a spec; handles versioned and classic module layouts; case-insensitive on Linux/Mac
  • SpecFileReader — reads and converts ModuleFast / PSResourceGet / PSDepend spec files (.psd1, .json, .ps1, .psm1); auto-detects format
  • PathHelper — manages PSModulePath env var and user profile; accesses the default module path via reflection into the private PowerShellConfig API; InstallScope enum
  • ModuleFastPlanner — async parallel resolution loop using Task.WhenAny; NuGet v3 paging; all HTTP requests cached
  • ModuleFastInstaller — parallel download and ZipArchive extraction using Task.WhenAllno runspaces, no Start-ThreadJob

Binary cmdlets

Cmdlet Replaces
Install-ModuleFast Install-ModuleFast + Install-ModuleFastHelper (all 3 parameter sets)
Get-ModuleFastPlan Get-ModuleFastPlan
Clear-ModuleFastCache Clear-ModuleFastCache
Import-ModuleManifest Import-ModuleManifest (now a public exported cmdlet)

psm1 / psd1 changes

  • ModuleFast.psm1 probes artifacts/bin/ModuleFast/debug/, then artifacts/bin/ModuleFast/release/, then falls back to the classic deployed bin/ModuleFast/ path; registers type accelerators for [ModuleFastSpec], [ModuleFastInfo], [SpecFileType], and [InstallScope]; OnRemove block cleans them up
  • ModuleFast.psd1: FunctionsToExport = @(), CmdletsToExport lists all 4 binary cmdlets

Test updates

  • ModuleFast.tests.ps1: all InModuleScope wrappers removed — ModuleFastSpec and Import-ModuleManifest are now public binary types/cmdlets accessible without module scope
  • Imports via ModuleFast.psd1 (manifest) rather than directly dotting ModuleFast.psm1

Build integration

  • ModuleFast.build.ps1: BuildCSharp task drops the -o flag (artifacts path managed by the SDK); CopyFiles task reads from artifacts/bin/ModuleFast/release/ when staging the module output
  • Old GetNugetVersioningAssembly / AddNugetVersioningAssemblyRequired tasks are superseded by the NuGet package reference in Directory.Packages.props
  • artifacts/ added to .gitignore

⌨️ Start Copilot coding agent tasks without leaving your editor — available in VS Code, Visual Studio, JetBrains IDEs and Eclipse.

Copilot AI and others added 3 commits March 20, 2026 18:51
- Add C# project (src/ModuleFast/ModuleFast.csproj) targeting net8.0
- Implement ModuleFastSpec in C# with full NuGet version range support
- Implement ModuleFastInfo in C# with IComparable and implicit ModuleSpecification conversion
- Add ModuleFastClient HTTP client factory helper
- Add stub binary cmdlets: GetModuleFastPlanCommand, ClearModuleFastCacheCommand
- Remove PowerShell class definitions from ModuleFast.psm1
- Register type accelerators for ModuleFastSpec and ModuleFastInfo in psm1
- Update ModuleFast.psd1 to export binary cmdlets
- Update ModuleFast.build.ps1 with BuildCSharp task
- Update .gitignore to exclude build artifacts
- Add ModuleFast.slnx solution file

All 7 non-E2E Pester tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…pdate-TypeData

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI changed the title [WIP] Refactor project to use C# binary modules instead of PowerShell script Refactor ModuleFast toward C# binary module; update Pester tests to match Mar 20, 2026
Copilot AI requested a review from JustinGrote March 20, 2026 19:04
@JustinGrote
Copy link
Owner

@copilot Convert the following powershell functions and any dependent functions into C# Cmdlets:
Install-ModuleFast
Get-ModuleFastPlan
Clear-ModuleFastCache
Install-ModuleFastHelper
Import-ModuleManifest
ConvertFrom-PSResourceGet
Get-ModuleInfoAsync
Add-DestinationToPSModulePath
Find-LocalModule
ConvertFrom-RequiredSpec
Select-RequiredSpecFileType
Read-RequiredSpecFile
ConvertFrom-ModuleManifest
Approve-Action
Get-PSDefaultModulePath

- Add InstallModuleFastCommand, GetModuleFastPlanCommand, ClearModuleFastCacheCommand, ImportModuleManifestCommand cmdlets
- Add ModuleFastPlanner (async HTTP planning with Task.WhenAll)
- Add ModuleFastInstaller (parallel download+extract, no runspaces)
- Add ModuleManifestReader (handles dynamic .psd1 manifests)
- Add LocalModuleFinder (searches PSModulePaths for installed modules)
- Add SpecFileReader (ModuleFast/PSResourceGet/PSDepend spec file formats)
- Add PathHelper (PSModulePath management, profile updates)
- Add ModuleFastCache (singleton ConcurrentDictionary request cache)
- Add NuGetModels (JSON models for NuGet v3 Registration API)
- Update ModuleFastInfo: make ModuleVersion, Location, Guid settable; IsLocal computed
- Update ModuleFastClient: add PSCredential support, ToAuthHeader, HTTP/3
- Update ModuleFast.psm1: simplified to DLL load + type accelerators only
- Update ModuleFast.psd1: FunctionsToExport=@(), CmdletsToExport with all 4 cmdlets
- Update ModuleFast.tests.ps1: remove InModuleScope wrapper (Import-ModuleManifest is now a public cmdlet)
- Add SpecFileType and InstallScope enums in C#

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Author

Copilot AI commented Mar 20, 2026

@copilot Convert the following powershell functions and any dependent functions into C# Cmdlets:
Install-ModuleFast
Get-ModuleFastPlan...

Done in commit 4e1f6bf. All 15 functions (plus their helpers) are now C# binary cmdlets/classes:

PowerShell function C# equivalent
Install-ModuleFast InstallModuleFastCommand — all 3 param sets
Get-ModuleFastPlan GetModuleFastPlanCommand
Clear-ModuleFastCache ClearModuleFastCacheCommand
Import-ModuleManifest ImportModuleManifestCommand + ModuleManifestReader
Install-ModuleFastHelper ModuleFastInstaller — uses Task.WhenAll, no runspaces/ThreadJob
Get-ModuleInfoAsync ModuleFastPlanner.GetModuleInfoAsync + GetCachedStringAsync
Find-LocalModule LocalModuleFinder.FindLocalModule
ConvertFrom-RequiredSpec SpecFileReader.ConvertFromRequiredSpec
Select-RequiredSpecFileType SpecFileReader.SelectRequiredSpecFileType
Read-RequiredSpecFile SpecFileReader.ReadRequiredSpecFile
ConvertFrom-PSResourceGet SpecFileReader.ConvertFromPSResourceGet
Add-DestinationToPSModulePath PathHelper.AddDestinationToPSModulePath
Get-PSDefaultModulePath PathHelper.GetPSDefaultModulePath
Approve-Action PathHelper.ApproveAction
ConvertFrom-PSDepend SpecFileReader.ConvertFromPSDepend

ModuleFast.psm1 is now just DLL loading + type accelerator registration. The planning loop uses Task.WhenAny and installation uses Task.WhenAll for parallel downloads and extraction.

Copilot AI changed the title Refactor ModuleFast toward C# binary module; update Pester tests to match Refactor ModuleFast to C# binary module — full cmdlet conversion Mar 20, 2026
@JustinGrote
Copy link
Owner

@copilot Reconfigure to use Artifacts Output Layout and Central Package Management

…ge Management (Directory.Packages.props)

Co-authored-by: JustinGrote <15258962+JustinGrote@users.noreply.github.com>
Agent-Logs-Url: https://github.com/JustinGrote/ModuleFast/sessions/74b5c2fa-04b4-44e8-830a-7e868b2d0871
Copy link
Author

Copilot AI commented Mar 20, 2026

@copilot Reconfigure to use Artifacts Output Layout and Central Package Management

Done in commit 4da8061.

Artifacts Output Layout (Directory.Build.props):

  • UseArtifactsOutput=true — all build outputs now land in artifacts/bin/ModuleFast/{debug,release}/ instead of src/ModuleFast/bin/
  • ModuleFast.psm1 probes artifacts/bin/ModuleFast/debug/, then release/, then falls back to the classic deployed bin/ModuleFast/ path
  • ModuleFast.build.ps1: BuildCSharp drops the -o flag; CopyFiles reads from artifacts/bin/ModuleFast/release/ when staging the module

Central Package Management (Directory.Packages.props):

  • ManagePackageVersionsCentrally=true with Microsoft.PowerShell.SDK 7.4.6 and NuGet.Versioning 6.8.0
  • ModuleFast.csproj PackageReference entries no longer carry Version attributes

Copilot AI changed the title Refactor ModuleFast to C# binary module — full cmdlet conversion Refactor ModuleFast to C# binary module — full cmdlet conversion with Artifacts Output Layout and Central Package Management Mar 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants